//
//  BaseModel.m
//  TestDemo
//
//  Created by fengxijun on 2/29/16.
//  Copyright © 2016 goappbox. All rights reserved.
//

#import "BaseModel.h"
#import <objc/runtime.h>

@implementation BaseModel

-(void)testRun
{
    NSLog(@"testRun");
//    [self exchangeMethod];
    //    [self performSelector:@selector(doSomething)];
}

-(void)exchangeMethod
{
    NSLog(@"需要交换的操作函数");
}

//SEL执行函数的过程:对象中有IML则直接执行对象中的函数IML,对于无法解读的消息执行resolveInstanceMethod返回BOOL, 检查某个SEL是否可执行
+ (BOOL) resolveInstanceMethod:(SEL)sel
{
//    BOOL isResolve = [super resolveClassMethod:sel];
//    return isResolve;
//    NSString *selString = NSStringFromSelector(sel);
//    if ([selString substringFromIndex:<#(NSUInteger)#>]) {
//        <#statements#>
//    }
    SEL t_sel = sel_registerName("doSomething");
    if (sel == t_sel) {
        NSLog(@"add method here");
        class_addMethod([self class], sel, (IMP)dynamicMethodIMP, method_getTypeEncoding(class_getInstanceMethod([self class], t_sel)));
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

//若SEL可执行则执行对象中的IML函数.否则执行forwardingTargetForSelector函数返回一个id类型对象,返回的id对象开始对SEL进行执行
-(id)forwardingTargetForSelector:(SEL)aSelector
{
    return nil;
//    return self;
//    return [[NSObject alloc] init];
}

//若forwardingTargetForSelector返回为nil或者self执行对象中的methodSignatureForSelector返回NSMethodSignature  ,若methodSignatureForSelector返回nil则调用doesNotRecognizeSelector抛出异常,返回有效的NSMethodSignature对象则执行
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    return nil;
}

-(void)forwardInvocation:(NSInvocation *)anInvocation
{
}

-(void)doesNotRecognizeSelector:(SEL)aSelector
{
}

void dynamicNoParamsMethodIMP (id self, SEL _cmd) {
    NSLog(@"%@ : %@",[[self class] description],NSStringFromSelector(_cmd));
}

void dynamicMethodIMP (id self, SEL _cmd,id list,...) {
//    NSLog(@"doSomething SEL");
    NSMutableArray *argsArray = [[NSMutableArray alloc] init];
    va_list params;
    va_start(params, list);
    id arg;
    if (_cmd) {
        //将第一个参数添加到数组
        id prev = list;
        [argsArray addObject:prev];
    }
    while ((arg = va_arg(params, id))) {
        if (arg) {
            [argsArray addObject:arg];
        }
    }
    
    va_end(params);
    
    NSLog(@"%@ : %@ : %@",[[self class] description],NSStringFromSelector(_cmd),argsArray);
}

@end
